package com.jnu.experience07.views;

import java.util.ArrayList;
import java.util.Iterator;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.jnu.experience07.R;

public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    public final static int STOP = 0;
    public final static int LEFT = 1;
    public final static int RIGHT = 2;
    public final static int FRAME_RATE = 60;
    private final static int REFILL_TIME = 75;
    private final static int EXPLODE_TIME = 5;

    private ArrayList<Bomb> bombList;	//存放所有炸弹的表
    private ArrayList<Foe> foeList;		//存放敌人的表
    private int ammo;	//剩余弹药量
    private int xPos;
    private int yPos;
    private int width;	//屏幕宽度
    private int height;	//屏幕高度
    private int boatSpeed;
    private int bombSpeed;
    private int boatWidthHalf; //船只宽度的一半
    private int boatHeightHalf;
    private int foeWidthHalf;
    private int foeHeightHalf;
    private int bombRadius;
    private int foeSpeedSlow;
    private int foeSpeedFast;
    private int refillTimer;
    private int explodeTimer;	//控制爆炸效果的时间
    private int layerHeight;
    private long time;
    private long cTime;
    private SurfaceHolder surfaceHolder;
    private boolean exitThread = false;
    private boolean haveFoes = false;
    private boolean running;
    private int direction;
    private Canvas canvas;
    private Foe foe;
    private Bitmap backgroundPic;	//背景图片
    private Bitmap boatPic;
    private Bitmap subPicR;
    private Bitmap subPicL;
    private Bitmap explodePic;
    private Bitmap bombPic;
    public static final String UPDATE_AMMO = "UPDATE_AMMO";
    public static final String UPDATE_SCORE_10 = "UPDATE_SCORE_10";
    private Rect surfaceFrame;	//确定sufaceView的显示范围
    private Context mContext;
    private Rect boatRect;	//船只占据的矩形区域
    private Rect explodeRect;
    private Rect bombRect;
    private Rect foeRect;


    public GameView(Context context) {
        super(context);
        mContext = context;
        surfaceHolder = this.getHolder();
        surfaceHolder.addCallback(this);
        bombList = new ArrayList<Bomb>();
        foeList = new ArrayList<Foe>();
        ammo = 100;
        refillTimer = REFILL_TIME;
        explodeTimer = EXPLODE_TIME;
        backgroundPic =
                BitmapFactory.decodeResource(getResources(), R.drawable.bg); //加载背景图片
        boatPic = BitmapFactory.decodeResource(getResources(), R.drawable.destoryer);
        subPicR = BitmapFactory.decodeResource(getResources(), R.drawable.sub_1r);
        subPicL = BitmapFactory.decodeResource(getResources(), R.drawable.sub_1l);
        explodePic = BitmapFactory.decodeResource(getResources(), R.drawable.explode);
        bombPic = BitmapFactory.decodeResource(getResources(), R.drawable.depth_charge);
    }

    public void createBomb() {
        if(ammo > 0) {
            Bomb b = new Bomb(xPos, yPos, bombSpeed, height);
            bombList.add(b);
            b.startThread();
            ammo--;
        }
    }


    public void refill() { //装填炮弹
        if(ammo < 100)
            ammo++;
    }
    public int getAmmoCount() { //返回剩余弹药数量
        return ammo;
    }

    public void startThread() {
        exitThread = false;
        running = true;
        new Thread(this).start();
    }

    public void stopThread() {
        exitThread = true;
    }

    public void pauseGame() {
        running =  false;
    }

    public void resumeGame() {
        running = true;
    }

    public void setDirection(int direct) {
        direction = direct;
    }

    public void run() {
        while(!exitThread) {
            if(running) {
                if(ammo != 100) {
                    refillTimer--;
                    if(refillTimer < 0) {
                        refill();
                        refillTimer = REFILL_TIME;
                        Intent i = new Intent(UPDATE_AMMO);
                        mContext.sendBroadcast(i);
                    }
                }

                switch(direction) {
                    case LEFT:
                        moveLeftBoat();
                        draw();
                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        break;
                    case RIGHT:
                        moveRightBoat();
                        draw();
                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        break;
                    default:
                        draw();
                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        break;
                }
            } else {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }


    }

    public void moveLeftBoat() {
        if(xPos - boatWidthHalf < 0 ) {
            xPos = boatWidthHalf;
        } else {
            xPos -= boatSpeed;
        }

    }
    public void moveRightBoat() {
        if(xPos + boatWidthHalf > width ) {
            xPos = width - boatWidthHalf;
        } else {
            xPos += boatSpeed;
        }
    }

    public void draw() {
        synchronized(surfaceHolder){
            canvas = surfaceHolder.lockCanvas();
            canvas.drawBitmap(backgroundPic, null, surfaceFrame, null);	//绘制背景图像
            boatRect.set(xPos-boatWidthHalf, yPos-boatHeightHalf, xPos+boatWidthHalf, yPos+boatHeightHalf);
            canvas.drawBitmap(boatPic, null, boatRect, null);
            //为了删除数据使用迭代器，先前使用数组导致程序闪退
            Iterator<Bomb> bIter = bombList.iterator();
            while (bIter.hasNext()) {
                Bomb b = bIter.next();
                for(int i=0; i<foeList.size(); i++) {
                    foe = foeList.get(i);
                    if(hit(b,foe)) {
                        b.setExplode(true);
                        foe.setHitStatus(true);
                        explodeRect.set(
                                b.getPositionX()-boatWidthHalf, b.getPositionY()-boatWidthHalf, b.getPositionX()+boatWidthHalf, b.getPositionY()+boatWidthHalf);
                        canvas.drawBitmap(explodePic, null, explodeRect, null);
                        explodeTimer--;
                    }
                }
                if (!b.isExplode()) {
                    bombRect.set(
                            b.getPositionX() - bombRadius, b.getPositionY() - bombRadius, b.getPositionX() + bombRadius, b.getPositionY() + bombRadius);
                    canvas.drawBitmap(bombPic, null, bombRect, null);
                } else {
                    bIter.remove();
                }
            }
            if(haveFoes) {
                for(int i=0; i<foeList.size(); i++) {
                    foe = foeList.get(i);
                    if(foe.getPositionX() <= width+foeWidthHalf && foe.getPositionX() >= -foeWidthHalf) {
                        if(foe.getHitStatus()) {
                            Intent intent = new Intent(UPDATE_SCORE_10);
                            mContext.sendBroadcast(intent);
                            foe.reset();
                        } else {
                            drawFoe(canvas,foe);
                            foe.move();
                        }
                    }
                    else
                        foe.reset();
                }
            }
            if(explodeTimer < EXPLODE_TIME && explodeTimer >= 0) {
                canvas.drawBitmap(explodePic, null, explodeRect, null);
                explodeTimer--;
            } else if(explodeTimer < 0) {
                explodeTimer = EXPLODE_TIME;
            }
            surfaceHolder.unlockCanvasAndPost(canvas);
        }
    }

    public void drawFoe(Canvas canvas, Foe f) {

        int x = f.getPositionX();
        int y = height - (f.getLayer() * layerHeight);
        foeRect.set(x-foeWidthHalf, y-foeHeightHalf, x+foeWidthHalf, y+foeHeightHalf);
        if(f.getDirection() == LEFT)
            canvas.drawBitmap(subPicL, null, foeRect, null);
        else
            canvas.drawBitmap(subPicR, null, foeRect, null);
    }

    public boolean hit(Bomb b, Foe f) {
        if(b.getPositionX() <= f.getPositionX() + foeWidthHalf
                && b.getPositionX() >= f.getPositionX() - foeWidthHalf) {
            if(b.getPositionY() >= height - (f.getLayer() * layerHeight) - foeHeightHalf
                    && b.getPositionY() <= height - (f.getLayer() * layerHeight) + foeHeightHalf)
                return true;
            else return false;
        } else {
            return false;
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        double tempValue;
        surfaceFrame = holder.getSurfaceFrame();
        width = surfaceFrame.width();
        height = surfaceFrame.height();
        xPos = width / 2;
        tempValue = height / 4.25;
        yPos = (int)tempValue;
        boatSpeed = width / 80;
        foeSpeedSlow = boatSpeed / 3;
        tempValue = boatSpeed * 0.8;
        foeSpeedFast = (int)tempValue; //一艘潜艇
        bombSpeed = height / 90;
        boatWidthHalf = width /20;
        boatHeightHalf = boatWidthHalf / 2;
        foeWidthHalf = width /24;
        foeHeightHalf = foeWidthHalf / 3;
        bombRadius = boatWidthHalf / 4;
        layerHeight = height / 7; //每层高度固定为1/7屏幕高度
        boatRect = new Rect();
        foeRect = new Rect();
        explodeRect = new Rect();
        bombRect = new Rect();
        draw();

        for(int i=0; i<3; i++) {
            Foe f = new Foe(width, i+1, foeSpeedSlow);
            foeList.add(f);
        }

        haveFoes = true;
        startThread();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        exitThread = true;
        haveFoes = false;
        //销毁时让线程暂停时间
        try
        {
            Thread.sleep(300);
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }

    public SurfaceHolder getSurfaceHolder() {
        return surfaceHolder;
    }

}
